﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using SvnCore;

using SVNTreeViewer.Views;
using SVNTreeViewer.VisualTreeBuilder;

namespace MultiLayerCanvasTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public List<ConnectionDetails> TestList = new List<ConnectionDetails>();

        private readonly Brush strokeColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF89C3E8"));

        public MainWindow()
        {
            InitializeComponent();
            this.PaintPath();
        }

        private void PaintPath()
        {
            this.DrawLine(new Point(10, 10), new Point(100, 100), 1);
            this.DrawLine(new Point(40, 10), new Point(140, 100), 3);
            this.DrawLine(new Point(20, 10), new Point(180, 100), 1);
            this.DrawLine(new Point(190, 10), new Point(280, 100), 2);

            //// this.DrawLineUp(new Point(10, 300), new Point(100, 100), "C");
        }

        private void DrawLine(Point p1, Point p2, long destination)
        {
            int step = this.Detection(p1, p2, destination);

            Polyline black = new Polyline
            {
                Stroke = this.strokeColor,
                StrokeThickness = 3,
                Points = new PointCollection()
                        {
                            p1,
                            new Point(p1.X, p2.Y - step - 20),
                            new Point(p2.X, p2.Y - step - 20),
                            p2
                        }
            };

            this.TestList.Add(new ConnectionDetails()
                {
                    Depth = p2.Y - step,
                    StartPoint = p1,
                    EndPoint = p2,
                    Destination = destination
                });

            this.grid.Children.Add(black);
        }

        private void DrawLineUp(Point p1, Point p2, long destination)
        {
            int step = this.Detection(p1, p2, destination);

            Polyline black = new Polyline
            {
                Stroke = this.strokeColor,
                StrokeThickness = 3,
                Points = new PointCollection()
                        {
                            p1,
                            new Point(p1.X, p2.Y + step + 20),
                            new Point(p2.X, p2.Y + step + 20),
                            p2
                        }
            };

            this.TestList.Add(new ConnectionDetails()
                {
                    Depth = p2.Y + step,
                    StartPoint = p1,
                    EndPoint = p2
                });

            this.grid.Children.Add(black);
        }

        private bool DoLinesIntersect(Point existingPointStart, Point existingPointEnd, Point newPointStart, Point newPointEnd)
        {
            return this.CrossProduct(existingPointStart, existingPointEnd, newPointStart) !=
                   this.CrossProduct(existingPointStart, existingPointEnd, newPointEnd) ||
                   this.CrossProduct(newPointStart, newPointEnd, existingPointStart) !=
                   this.CrossProduct(newPointStart, newPointEnd, existingPointEnd);
        }

        private double CrossProduct(Point p1, Point p2, Point p3)
        {
            return ((p2.X - p1.X) * (p3.Y - p1.Y)) - ((p3.X - p1.X) * (p2.Y - p1.Y));
        }

        private int Detection(Point p1, Point p2, long destination, int step = 0)
        {
            ConnectionDetails colision =
                this.TestList.FirstOrDefault(
                    x =>
                    x.Depth == p2.Y - step
                    && this.DoLinesIntersect(x.StartPoint, x.EndPoint, p1, p2)
                    && x.Destination != destination);

            return colision != null ? 20 + this.Detection(p1, new Point(p2.X, p2.Y), destination, 20 + step) : 0;
        }
    }
}
